package com.hx.test.domain;

import lombok.Data;
import lombok.ToString;
import lombok.experimental.Accessors;
import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;
import java.util.List;

/**
 * :@NamedEntityGraph :注解在实体上 , 解决典型的N+1问题
 *  name表示实体图名, 与 repository中的注解 @EntityGraph的value属性相对应,
 *  attributeNodes 表示被标注要懒加载的属性节点 比如此例中 : 要懒加载的子分类集合users
 *
 *  @NamedEntityGraph(
 *       name = "universityWithTeacherAndStudent",
 *       attributeNodes = {@NamedAttributeNode(value = "teachers", subgraph = "teacherWithStudent")},
 *       subgraphs = {
 *             @NamedSubgraph(name = "teacherWithStudent", attributeNodes = {@NamedAttributeNode("students")})
 *       }
 * )
 *
 * 通过注解的方式我们在实体上用 @NamedEntityGraph 来定义一个实体图，
 * name属性指定一个实体图的名称，attributeNodes 属性指定要立即加载的节点，
 * 节点用 @NamedAttributeNode 定义，其中 values 表示节点的属性名称，在本例中是 teachers 这个属性，
 * 而如果还想加载teacher节点下的students属性的话，需要再为该节点定义一个子图，
 * 子图用 @NamedSubgraph 来定义并用subgraph来引用，方式与 @NamedEntityGraph 一样，
 * 这样我们就定义了一个以 university 为起点，到 teacher 再到student 的路径
 */
@Entity
@Table(name = "t_role")
@Data
@ToString(exclude = {"users"})
@Accessors(chain = true)
@NamedEntityGraph(name = "Role.Graph", attributeNodes = {@NamedAttributeNode("resources")})
public class Role {

    @Id
    @GeneratedValue(generator = "UUID")
    @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
    @Column(name = "id")
    private String id;

    @Column(name = "name")
    private String name;

    @ManyToMany(mappedBy = "roles",cascade = CascadeType.ALL,fetch = FetchType.LAZY)
//    @ManyToMany(cascade = CascadeType.ALL)
    //@JoinTable(name = "t_user_role",joinColumns =@JoinColumn(name = "role_id"),inverseJoinColumns = @JoinColumn(name = "user_id"))
    private List<User> users;


    @ManyToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY)
    @JoinTable(name = "t_role_resource",joinColumns = @JoinColumn(name = "role_id"),inverseJoinColumns = @JoinColumn(name = "resource_id"))
    private List<Resource> resources;
}
